cc.Class({
    extends: cc.Component,

    properties: {
        guide: cc.Node,
        needRotation: cc.Node,
        bullet: cc.Prefab,
        bulletLayer: cc.Node,
        fireEffect: cc.Node,
        attackcircle: cc.Node,
        hurtLabel: cc.Prefab,
        hpProgress: cc.ProgressBar,
        hpLabel: cc.Label,
        warn: cc.Node,
        bulletLabel: cc.Label,
        bulletProgress: cc.ProgressBar,
        shieldLabel: cc.Label,
        shieldProgress: cc.ProgressBar,
        shield: cc.Node,

        hp: {
            set(x) { 
                this._hp = x;
                if (this._hp < 0) this._hp = 0;
                if (this._hp > this.hpmax) this._hp = this.hpmax;
                this.hpLabel.string = this._hp;
                this.hpProgress.progress = this._hp / this.hpmax;
            },
            get() {
                return this._hp;
            }
        },

        hpmax: {
            set(x) { 
                this._hpmax = x;
            },
            get() {
                return this._hpmax;
            }
        },

        shieldhp: {
            set(x) { 
                this._shieldhp = x;
                if (this._shieldhp < 0) this._shieldhp = 0;
                if (this._shieldhp > this.shieldhpmax) this._shieldhp = this.shieldhpmax;
                
                this.shieldLabel.string = this._shieldhp;
                this.shieldProgress.progress = this._shieldhp / this.shieldhpmax;
            },
            get() {
                return this._shieldhp;
            }
        },

        shieldhpmax: {
            set(x) { 
                this._shieldhpmax = x;
            },
            get() {
                return this._shieldhpmax;
            }
        },

        bulletCnt: {
            set(x) { 
                this._bulletCnt = x;
                this.bulletLabel.string = `${this._bulletCnt} / ${this.bulletMax}`;
            },
            get() {
                return this._bulletCnt;
            }
        },

        bulletMax: {
            set(x) { 
                this._bulletMax = x;
                this.bulletLabel.string = `${this._bulletCnt} / ${this.bulletMax}`;
            },
            get() {
                return this._bulletMax;
            }
        }
    },

    //查找最近的怪物
    findClosedMonster() {
        let mindis = cc.v2(9999, 9999); //设置一个最小的距离
        let pos = this.node.getPosition();
        let targetid = -1; //距离最近的目标id
        for (let monster of g_Monster.getAllMonster()) {
            let dis = monster.getPosition().sub(pos);
            if (dis.mag() < mindis.mag() && dis.mag() <= this.attackRange) {
                mindis = dis;
                targetid = monster.id;
                //console.log(targetid);
            }
        }
        this.isFight = targetid != -1;
        return targetid;
    },

    //攻击
    doFire() {
        if (g_Game.isPalse()) return;
        if (this.bulletCnt <= 0) return;
        //设置枪头朝着怪物移动
        let targetid = this.findClosedMonster(); //距离最近的目标id
        if (targetid == -1) return;
        let monster = g_Monster.getMonster(targetid);
        
        let dis = monster.getPosition().sub(this.node.getPosition()); //计算两向量距离
        let hd = cc.v2(1, 0).signAngle(dis); //计算两向量夹角弧度
        let angle = (hd * 180) / Math.PI; //计算角度
        this.needRotation.angle = angle - 90; //转动枪头朝向

        g_Audio.playEffect("fire101"); //播放音效

        
        this.shootToward(angle);
        this.bulletCnt--;
        if (this.bulletCnt <= 0) {//子弹用完
            this.bulletCDCnt = this.bulletCD;//重置子弹冷却时间
        }

        // cc.log(this.shootSpeed / this.shootRetio);
        // cc.log(this.shootRetio);
    },

    //子弹弹道方向
    shootToward(angle) {
        let cnt = this.shootLine; //子弹数量
        let backCnt = this.backLine;
        if (cnt % 2 == 0) {
            this.ShootBullet(angle);
            cnt--;
        }
        
        for (let i = 1; i <= cnt; ++i) {
            let k = i % 2 == 1 ? 1 : -1;//判断奇偶
            let tempAngle = angle + k * Math.ceil(i / 2) * 15;//计算角度
            this.ShootBullet(tempAngle);
        }
        if (backCnt > 0) {
            if (backCnt % 2 == 0) {
                this.ShootBullet(angle + 180, false);
                backCnt--;
            }
            for (let i = 1; i <= backCnt; ++i) {
                let k = i % 2 == 1 ? 1 : -1;//判断奇偶
                let tempAngle = angle - k * Math.ceil(i / 2) * 15;//计算角度
                this.ShootBullet(tempAngle + 180, false);
            }
        }
        
    },

    //增加子弹弹道
    ShootBullet(angle, flag = true) {
        let bullet = cc.instantiate(this.bullet); //实例化子弹
        let pos = this.fireEffect.convertToWorldSpaceAR(cc.v2(0, 0)); //将世界坐标转换为节点坐标
        
        if (!flag) { 
            pos = this.needRotation.convertToWorldSpaceAR(cc.v2(0, 0)); //将节点坐标转换为世界坐标
        }
        pos = this.bulletLayer.convertToNodeSpaceAR(pos); //将节点坐标转换为世界坐标
        this.bulletLayer.addChild(bullet); //添加到子弹层
        g_Bullet.addBullet(bullet); //添加到子弹列表

        let hd = (angle * Math.PI) / 180; //弧度
        bullet.owner = this; //设置子弹所属者
        bullet.hd = hd; //设置子弹弧度
        bullet.attack = this.attack(); //设置子弹攻击力
        bullet.setPosition(pos); //设置子弹位置
        bullet.startpos = pos; //记录子弹起始位置
        
        bullet.angle = angle - 90; //子弹角度的朝向
    },

    //增加换弹速度
    delbulletCD(ratio) {
        this.bulletCD -= ratio;
    },

    //增加子弹数量
    addbulletMax(ratio) {
        this.bulletMax += ratio;  
        this.bulletCnt = this.bulletMax;
    },

    //子弹冷却
    refreshBulletCD() {
        if (this.bulletCDCnt <= 0) { 
            if (this.bulletProgress.node.active) { //子弹冷却中
                this.bulletProgress.node.active = false;
                this.bulletCnt = this.bulletMax;
                g_Audio.playEffect("grub1"); //播放音效
            }
            return;
        } 
        this.bulletProgress.node.active = true;
        this.bulletProgress.progress = (this.bulletCD - this.bulletCDCnt) / this.bulletCD;
        
        // if (this.bulletCnt <= 0) {
        //     this.bulletCDCnt += dt;
        //     if (this.bulletCDCnt >= this.bulletCD) { 
        //         this.bulletCDCnt = 0;
        //         this.bulletCnt = this.bulletMax;
        //     }
        //     this.bulletProgress.progress = this.bulletCDCnt / this.bulletCD;
        // }
    },

    

    //当发生碰撞时调用
    onCollisionEnter(other, self) {
        if (other.node.group == "decorate") {
            other.node.opacity = 125;
        }
    },

    onCollisionExit(other, self) {
        if (other.node.group == "decorate") {
            other.node.opacity = 255;
        }
    },

    setth(hd) {
        this.hd = hd;//设置弧度
    },

    doMove() {
        //node.x
        //node.y
        //this是当前脚本文件
        //组件.node 获取组件所在的结点
        let x = 0;
        let y = 0;
        if (this.hd) {
            let angle = (this.hd * 180) / Math.PI;
            let pos = this.node.getPosition(); //获取人物当前位置
            x = this.speed * Math.cos(this.hd); //计算x方向移动距离
            y = this.speed * Math.sin(this.hd); //计算y方向移动距离

            pos.x += x; //移动
            pos.y += y;
            pos = pos.clampf(cc.v2(-1080, -1600), cc.v2(1080, 1600)); //限定移动边界

            this.node.setPosition(pos);
            this.guide.angle = angle - 90;
            if (!this.isFight) {
                this.needRotation.angle = angle - 90;
            }
        }
    },

    //增加技能
    addSkill(skill) {
        let obj = g_Skill.create(skill);
        this.skillList.push(obj);
        obj.owner = this;
        obj.load();
    },


    //增加护盾
    addShield(cd) {
        this.shieldhpmax = Math.floor(this.hpmax * 0.2);
        this.shieldhp = this.shieldhpmax;
        this.shieldProgress.node.active = true; // 激活护盾节点
        this.ShieldCD = cd; // 设置护盾的冷却时间
        this.hasShield = true; // 护盾激活
        // this.ShieldCDCnt = this.ShieldCD; // 设置护盾冷却计数
        // this.shieldProgress.node.setPosition(this.node.getPosition()); //设置护盾的位置
    },


    //护罩冷却
    refreshShieldCD() {
        if (this.ShieldCDCnt <= 0 && this.hasShield) { 
            if (!this.shieldProgress.node.active) {
                this.addShield(3);
            }
            return;
        }
        this.shieldProgress.node.active = false;//关闭护盾  
        cc.log(this.shieldProgress.node.active,"护罩冷却中")
        
    },

    //增加射击速率
    addShootRatio(ratio) {
        this.shootRatio += ratio;
        this.schedule(this.doFire, this.shootSpeed / this.shootRatio);
    },

    //增加攻击力
    addAttackRatio(ratio) {
        this.attackRatio += ratio;
    },

    //增加暴击率
    addhitRate(ratio) { 
        this.hitRate = Math.min(1, this.hitRate + ratio);;//增加暴击率
    },

    //增加生命上限
    addhpMax(ratio) {
        this.hpmax = Math.ceil(this.hpmax * (1 + ratio));
        this.hp = this.hpmax;
        cc.log(this.hpmax);
    },

    //增加攻击范围
    addAttackRange(ratio) {
        this.attackRange += ratio;
        this.attackcircle.width = this.attackRange * 2;//获取攻击范围组件
        this.attackcircle.height = this.attackRange * 2;
    },

    getDeBuffSkill(id) {
        return this.debuffskill[id];
    },

    addDeBuffSkill(obj) {
        this.debuffskill[obj.id] = obj;
    },

    addBulletdebuff(monster) {
        for (let id in this.debuffskill) { 
            let obj = this.debuffskill[id];
            obj.addDebuff(monster);
        }
    },

    //人物攻击力
    attack() {
        return Math.floor(this.baseAttack * this.attackRatio);
    },

    //人物受伤
    receiveDamage(hurt) {
        if (this.shieldhp > 0) {
            this.shieldhp -= hurt;
        }
        else {
            this.ShieldCDCnt = this.ShieldCD;
            this.hp -= hurt;
        }
        g_Audio.playEffect("die"); //播放音效
            let hurtLabel = cc.instantiate(this.hurtLabel);
            cc.find("Canvas/hurtLayer").addChild(hurtLabel);
        hurtLabel.setPosition(this.node.getPosition());
        
        hurtLabel.getComponent(cc.Label).string = hurt;
        //getCompoent(获取系统组件用cc.Label; 获取自定义组件用"role")
            
        //hurtLabel.color = cc.color.RED; //使用系统默认的颜色：红色
        hurtLabel.color = cc.color(255, 225, 225); //使用自定义颜色：白色

        hurtLabel.runAction(
            cc.sequence(//串行执行多个动作
                cc.scaleTo(0.1, 1.3), //缩放到指定大小 （时间，缩放值）
                cc.spawn(//并行执行多个动作
                    cc.moveBy(1, 0, 200), //移动像素 （时间,x移动距离不变,y移动距离向上100）
                    cc.fadeOut(1), //淡出 （时间）
                    cc.scaleTo(1, 0) //缩放到指定大小 （时间，缩放值）
                ),

                cc.callFunc(() => {
                        //调用函数
                    hurtLabel.destroy();
                })
            )
        );

        if (this.hp <= 0) {
            g_Game.gameOver();
        }
        else {
            this.runDamageAction();
        }
    },

    //受伤红光闪烁特效
    runDamageAction() {
        this.warn.active = true;
        this.warn.opacity = 255;

        this.warn.runAction(
            cc.sequence(//串行执行多个动作
                cc.repeat(//重复执行动作
                    cc.sequence(
                        cc.fadeTo(0.2, 155), //淡入 （时间，透明度）
                        cc.fadeTo(0.2, 255), //淡入 （时间，透明度）
                    ),
                    3,
                ),
                cc.fadeOut(0.5), //淡出 （时间）
                cc.callFunc(() => {
                    this.warn.active = false;
                })
            )
        );
    },

    onLoad() {
        cc.log(this.shieldProgress);
        g_Slot.on(g_Lister.add_skill, (skill) => {
            this.addSkill(skill);
        });
    },

    onDestroy() {
        g_Slot.off(g_Lister.add_skill);
    },

    start() {
        this.skillList = [];
        this.debuffskill = [];
        this.hd = 0; //角度变化量
        this.speed = 5; //设置人物移动速度
        this.attackRange = 360; //攻击范围
        this.baseAttack = 50; //攻击力

        this.shootSpeed = 0.5;
        this.shootRatio = 1; //射击速率
        this.shootLine = 1; //子弹弹道
        this.attackRatio = 1; //攻击力倍率
        this.backLine = 0; //子弹背向弹道

        this.bulletMax = 20;
        this.bulletCnt = this.bulletMax;
        this.bulletCD = 3;//3秒冷却
        this.bulletCDCnt = 0;
        this.bulletProgress.node.active = false;
        this.shieldProgress.node.active = false;
        
        
        this.hpmax = 100;
        this.hp = this.hpmax;
        this.shieldhpmax = 0;
        this.shieldhp = this.shieldhpmax;
        this.ShieldCD = 0;
        this.ShieldCDCnt = 0;
        this.hitRate = 0;//暴击率

        this.warn.active = false;

        //cc.loader.loadRes(资源路径，资源类型，回调函数) 动态加载血量提示
        cc.loader.loadRes("panel/panelHurt", cc.Prefab, (err, item) => {
            if (err) {
                cc.log("资源加载错误", err);
                return;
            }
            this.hurtLabel = item;
        });

        this.schedule(this.doFire, this.shootSpeed / this.shootRatio); //每秒调用一次update函数
    },

    update(dt) {
        cc.log(this.shieldProgress.node.active,"初始状态")
        cc.log(this.ShieldCDCnt,"!!!!!!")
        if (g_Game.isPalse()) return;
        this.bulletCDCnt -= dt;
        this.ShieldCDCnt -= dt;
        this.refreshBulletCD();
        this.refreshShieldCD();
        this.doMove();
    },
});
